home *** CD-ROM | disk | FTP | other *** search
/ CU Amiga Super CD-ROM 14 / CU Amiga Magazine's Super CD-ROM 14 (1997)(EMAP Images)(GB)(Track 1 of 3)[!][issue 1997-09].iso / CUCD / Programming / Mesa-2.2 / src / texobj.c < prev    next >
Encoding:
C/C++ Source or Header  |  1997-03-13  |  13.9 KB  |  493 lines

  1. /* $Id: texobj.c,v 1.5 1997/02/09 18:52:15 brianp Exp $ */
  2.  
  3. /*
  4.  * Mesa 3-D graphics library
  5.  * Version:  2.2
  6.  * Copyright (C) 1995-1997  Brian Paul
  7.  *
  8.  * This library is free software; you can redistribute it and/or
  9.  * modify it under the terms of the GNU Library General Public
  10.  * License as published by the Free Software Foundation; either
  11.  * version 2 of the License, or (at your option) any later version.
  12.  *
  13.  * This library is distributed in the hope that it will be useful,
  14.  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  15.  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  16.  * Library General Public License for more details.
  17.  *
  18.  * You should have received a copy of the GNU Library General Public
  19.  * License along with this library; if not, write to the Free
  20.  * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  21.  */
  22.  
  23.  
  24. /*
  25.  * $Log: texobj.c,v $
  26.  * Revision 1.5  1997/02/09 18:52:15  brianp
  27.  * added GL_EXT_texture3D support
  28.  *
  29.  * Revision 1.4  1997/01/16 03:35:34  brianp
  30.  * added calls to device driver DeleteTexture() and BindTexture() functions
  31.  *
  32.  * Revision 1.3  1997/01/09 19:49:47  brianp
  33.  * added a check to switch rasterizers if needed in glBindTexture()
  34.  *
  35.  * Revision 1.2  1996/09/27 17:09:42  brianp
  36.  * removed a redundant return statement
  37.  *
  38.  * Revision 1.1  1996/09/13 01:38:16  brianp
  39.  * Initial revision
  40.  *
  41.  */
  42.  
  43.  
  44. #include <assert.h>
  45. #include <stdlib.h>
  46. #include "context.h"
  47. #include "macros.h"
  48. #include "teximage.h"
  49. #include "texobj.h"
  50. #include "types.h"
  51.  
  52.  
  53.  
  54. /*
  55.  * Allocate a new texture object structure.  The name and dimensionality are
  56.  * set to zero here and must be initialized by the caller.
  57.  */
  58. struct gl_texture_object *gl_alloc_texture_object( void )
  59. {
  60.    struct gl_texture_object *obj;
  61.  
  62.    obj = (struct gl_texture_object *)
  63.                      calloc(1,sizeof(struct gl_texture_object));
  64.    if (obj) {
  65.       /* init the non-zero fields */
  66.       obj->WrapS = GL_REPEAT;
  67.       obj->WrapT = GL_REPEAT;
  68.       obj->MinFilter = GL_NEAREST_MIPMAP_LINEAR;
  69.       obj->MagFilter = GL_LINEAR;
  70.    }
  71.    return obj;
  72. }
  73.  
  74.  
  75. /*
  76.  * Append a gl_texture_object struct to a list of texture objects.
  77.  */
  78. static void append_texture_object( struct gl_texture_object *list,
  79.                                    struct gl_texture_object *obj )
  80. {
  81.    struct gl_texture_object *t;
  82.  
  83.    t = list;
  84.    while (t->Next) {
  85.       t = t->Next;
  86.    }
  87.    t->Next = obj;
  88. }
  89.  
  90.  
  91.  
  92. /*
  93.  * Deallocate a texture object struct and all children structures
  94.  * and image data.
  95.  */
  96. void gl_free_texture_object( struct gl_texture_object *t )
  97. {
  98.    GLuint i;
  99.  
  100.    for (i=0;i<MAX_TEXTURE_LEVELS;i++) {
  101.       if (t->Image[i]) {
  102.          gl_free_texture_image( t->Image[i] );
  103.       }
  104.    }
  105.    free( t );
  106. }
  107.  
  108.  
  109. /*
  110.  * Given a texture object name, return a pointer to the texture object.
  111.  */
  112. static struct gl_texture_object *
  113. find_texture_object( GLcontext *ctx, GLuint name )
  114. {
  115.    struct gl_texture_object *t;
  116.  
  117.    assert( name>0 );
  118.    t = ctx->Shared->TexObjectList;
  119.    while (t) {
  120.       if (t->Name == name) {
  121.          return t;
  122.       }
  123.       t = t->Next;
  124.    }
  125.    return NULL;
  126. }
  127.  
  128.  
  129.  
  130.  
  131. void gl_GenTextures( GLcontext *ctx, GLsizei n, GLuint *textures )
  132. {
  133.    struct gl_texture_object *t;
  134.    GLuint i, max;
  135.  
  136.    if (INSIDE_BEGIN_END(ctx)) {
  137.       gl_error( ctx, GL_INVALID_OPERATION, "glGenTextures" );
  138.       return;
  139.    }
  140.    if (n<0) {
  141.       gl_error( ctx, GL_INVALID_VALUE, "glGenTextures" );
  142.       return;
  143.    }
  144.  
  145.    /* Find maximum texture object name in use */
  146.    t = ctx->Shared->TexObjectList;
  147.    max = 0;
  148.    while (t) {
  149.       if (t->Name>max) {
  150.          max = t->Name;
  151.       }
  152.       t = t->Next;
  153.    }
  154.  
  155.    /* Return new texture names starting at max+1 */
  156.    for (i=0;i<n;i++) {
  157.       max++;
  158.       textures[i] = max;
  159.    }
  160. }
  161.  
  162.  
  163.  
  164. void gl_DeleteTextures( GLcontext *ctx, GLsizei n, const GLuint *textures)
  165. {
  166.    GLuint i;
  167.  
  168.    if (INSIDE_BEGIN_END(ctx)) {
  169.       gl_error( ctx, GL_INVALID_OPERATION, "glAreTexturesResident" );
  170.       return;
  171.    }
  172.  
  173.    for (i=0;i<n;i++) {
  174.       struct gl_texture_object *t, *tprev, *tcurr;
  175.       if (textures[i]>0) {
  176.          t = find_texture_object( ctx, textures[i] );
  177.          if (t) {
  178.             if (ctx->Texture.Current1D==t) {
  179.                /* revert to default 1-D texture */
  180.                ctx->Texture.Current1D = ctx->Shared->TexObjectList;
  181.                t->RefCount--;
  182.                assert( t->RefCount >= 0 );
  183.             }
  184.             else if (ctx->Texture.Current2D==t) {
  185.                /* revert to default 2-D texture */
  186.                ctx->Texture.Current2D = ctx->Shared->TexObjectList->Next;
  187.                t->RefCount--;
  188.                assert( t->RefCount >= 0 );
  189.             }
  190.             else if (ctx->Texture.Current3D==t) {
  191.                /* revert to default 3-D texture */
  192.                ctx->Texture.Current3D = ctx->Shared->TexObjectList->Next;
  193.                t->RefCount--;
  194.                assert( t->RefCount >= 0 );
  195.             }
  196.             if (t->RefCount==0) {
  197.                /* remove texture object t from the linked list */
  198.                tprev = NULL;
  199.                tcurr = ctx->Shared->TexObjectList;
  200.                while (tcurr) {
  201.                   if (tcurr==t) {
  202.                      assert( tprev );
  203.                      tprev->Next = t->Next;
  204.                      gl_free_texture_object( t );
  205.                      break;
  206.                   }
  207.                   tprev = tcurr;
  208.                   tcurr = tcurr->Next;
  209.                }
  210.             }
  211.  
  212.             /* tell device driver to delete texture */
  213.             if (ctx->Driver.DeleteTexture) {
  214.                (*ctx->Driver.DeleteTexture)( ctx, textures[i] );
  215.             }
  216.          }
  217.       }
  218.    }
  219. }
  220.  
  221.  
  222.  
  223. void gl_BindTexture( GLcontext *ctx, GLenum target, GLuint texture )
  224. {
  225.    struct gl_texture_object *oldtexobj;
  226.    if (INSIDE_BEGIN_END(ctx)) {
  227.       gl_error( ctx, GL_INVALID_OPERATION, "glAreTexturesResident" );
  228.       return;
  229.    }
  230.    switch (target) {
  231.       case GL_TEXTURE_1D:
  232.          oldtexobj = ctx->Texture.Current1D;
  233.          if (texture==0) {
  234.             /* use default 1-D texture */
  235.             ctx->Texture.Current1D = ctx->Shared->TexObjectList;
  236.          }
  237.          else {
  238.             struct gl_texture_object *t;
  239.             t = find_texture_object( ctx, texture );
  240.             if (t) {
  241.                if (t->Dimensions==1) {
  242.                   /* success! */
  243.                   ctx->Texture.Current1D = t;
  244.                }
  245.                else {
  246.                   /* wrong dimensionality */
  247.                   gl_error( ctx, GL_INVALID_OPERATION, "glBindTextureEXT" );
  248.                   return;
  249.                }
  250.             }
  251.             else {
  252.                /* create new texture object */
  253.                t = gl_alloc_texture_object();
  254.                append_texture_object( ctx->Shared->TexObjectList, t );
  255.                t->Name = texture;
  256.                t->Dimensions = 1;
  257.                ctx->Texture.Current1D = t;
  258.             }
  259.          }
  260.          /* Tidy up reference counting */
  261.          if (ctx->Texture.Current1D != oldtexobj && oldtexobj->Name>0) {
  262.             /* decr reference count of the prev texture object */
  263.             oldtexobj->RefCount--;
  264.             assert( oldtexobj->RefCount >= 0 );
  265.          }
  266.          if (ctx->Texture.Current1D->Name>0) {
  267.             ctx->Texture.Current1D->RefCount++;
  268.          }
  269. #ifdef FOO
  270.          if (!ctx->Texture.Current1D->Complete) {
  271.             /* re-examine texture completeness */
  272.             gl_update_texture_state();
  273.          }
  274. #endif
  275.  
  276.          /* Check if we may have to use a new triangle rasterizer */
  277.          if (oldtexobj->WrapS != ctx->Texture.Current1D->WrapS
  278.              || oldtexobj->MinFilter != ctx->Texture.Current1D->MinFilter
  279.              || oldtexobj->MagFilter != ctx->Texture.Current1D->MagFilter) {
  280.             ctx->NewState |= NEW_RASTER_OPS;
  281.          }
  282.  
  283.          /* The current 1D texture object can never be NULL! */
  284.          assert(ctx->Texture.Current1D);
  285.          break;
  286.  
  287.       case GL_TEXTURE_2D:
  288.          oldtexobj = ctx->Texture.Current2D;
  289.          if (texture==0) {
  290.             /* use default 2-D texture */
  291.             ctx->Texture.Current1D = ctx->Shared->TexObjectList->Next;
  292.          }
  293.          else {
  294.             struct gl_texture_object *t;
  295.             t = find_texture_object( ctx, texture );
  296.             if (t) {
  297.                if (t->Dimensions==2) {
  298.                   /* success */
  299.                   ctx->Texture.Current2D = t;
  300.                }
  301.                else {
  302.                   /* wrong dimensionality */
  303.                   gl_error( ctx, GL_INVALID_OPERATION, "glBindTexture" );
  304.                   return;
  305.                }
  306.             }
  307.             else {
  308.                /* create new texture object */
  309.                t = gl_alloc_texture_object();
  310.                append_texture_object( ctx->Shared->TexObjectList, t );
  311.                t->Name = texture;
  312.                t->Dimensions = 2;
  313.                ctx->Texture.Current2D = t;
  314.             }
  315.          }
  316.          /* Tidy up reference counting */
  317.          if (ctx->Texture.Current2D != oldtexobj && oldtexobj->Name>0) {
  318.             /* decr reference count of the prev texture object */
  319.             oldtexobj->RefCount--;
  320.             assert( oldtexobj->RefCount >= 0 );
  321.          }
  322.          if (ctx->Texture.Current2D->Name>0) {
  323.             ctx->Texture.Current2D->RefCount++;
  324.          }
  325. #ifdef FOO
  326.          if (!ctx->Texture.Current2D->Complete) {
  327.             /* re-examine texture completeness */
  328.             gl_update_texture_state();
  329.          }
  330. #endif
  331.  
  332.          /* Check if we may have to use a new triangle rasterizer */
  333.          if (oldtexobj->WrapS != ctx->Texture.Current1D->WrapS
  334.              || oldtexobj->WrapT != ctx->Texture.Current1D->WrapT
  335.              || oldtexobj->MinFilter != ctx->Texture.Current1D->MinFilter
  336.              || oldtexobj->MagFilter != ctx->Texture.Current1D->MagFilter) {
  337.             ctx->NewState |= NEW_RASTER_OPS;
  338.          }
  339.  
  340.          /* The current 2D texture object can never be NULL! */
  341.          assert(ctx->Texture.Current2D);
  342.          break;
  343.  
  344.       case GL_TEXTURE_3D_EXT:
  345.          oldtexobj = ctx->Texture.Current3D;
  346.          if (texture==0) {
  347.             /* use default 3-D texture */
  348.             ctx->Texture.Current1D = ctx->Shared->TexObjectList->Next->Next;
  349.          }
  350.          else {
  351.             struct gl_texture_object *t;
  352.             t = find_texture_object( ctx, texture );
  353.             if (t) {
  354.                if (t->Dimensions==3) {
  355.                   /* success */
  356.                   ctx->Texture.Current3D = t;
  357.                }
  358.                else {
  359.                   /* wrong dimensionality */
  360.                   gl_error( ctx, GL_INVALID_OPERATION, "glBindTexture" );
  361.                   return;
  362.                }
  363.             }
  364.             else {
  365.                /* create new texture object */
  366.                t = gl_alloc_texture_object();
  367.                append_texture_object( ctx->Shared->TexObjectList, t );
  368.                t->Name = texture;
  369.                t->Dimensions = 3;
  370.                ctx->Texture.Current3D = t;
  371.             }
  372.          }
  373.          /* Tidy up reference counting */
  374.          if (ctx->Texture.Current3D != oldtexobj && oldtexobj->Name>0) {
  375.             /* decr reference count of the prev texture object */
  376.             oldtexobj->RefCount--;
  377.             assert( oldtexobj->RefCount >= 0 );
  378.          }
  379.          if (ctx->Texture.Current3D->Name>0) {
  380.             ctx->Texture.Current3D->RefCount++;
  381.          }
  382. #ifdef FOO
  383.          if (!ctx->Texture.Current3D->Complete) {
  384.             /* re-examine texture completeness */
  385.             gl_update_texture_state();
  386.          }
  387. #endif
  388.  
  389.          /* Check if we may have to use a new triangle rasterizer */
  390.          if (oldtexobj->WrapS != ctx->Texture.Current3D->WrapS
  391.              || oldtexobj->WrapT != ctx->Texture.Current3D->WrapT
  392.              || oldtexobj->MinFilter != ctx->Texture.Current3D->MinFilter
  393.              || oldtexobj->MagFilter != ctx->Texture.Current3D->MagFilter) {
  394.             ctx->NewState |= NEW_RASTER_OPS;
  395.          }
  396.  
  397.          /* The current 3D texture object can never be NULL! */
  398.          assert(ctx->Texture.Current3D);
  399.          break;
  400.  
  401.       default:
  402.          gl_error( ctx, GL_INVALID_ENUM, "glBindTexture" );
  403.          return;
  404.    }
  405.  
  406.    /* Pass BindTexture to device driver */
  407.    if (ctx->Driver.BindTexture) {
  408.       (*ctx->Driver.BindTexture)( ctx, target, texture );
  409.    }
  410. }
  411.  
  412.  
  413.  
  414. void gl_PrioritizeTextures( GLcontext *ctx,
  415.                             GLsizei n, const GLuint *textures,
  416.                             const GLclampf *priorities )
  417. {
  418.    GLuint i;
  419.  
  420.    if (INSIDE_BEGIN_END(ctx)) {
  421.       gl_error( ctx, GL_INVALID_OPERATION, "glAreTexturesResident" );
  422.       return;
  423.    }
  424.    if (n<0) {
  425.       gl_error( ctx, GL_INVALID_VALUE, "glAreTexturesResident(n)" );
  426.       return;
  427.    }
  428.  
  429.    for (i=0;i<n;i++) {
  430.       struct gl_texture_object *t;
  431.       if (textures[i]>0) {
  432.          t = find_texture_object( ctx, textures[i] );
  433.          if (t) {
  434.             t->Priority = CLAMP( priorities[i], 0.0F, 1.0F );
  435.          }
  436.       }
  437.    }
  438. }
  439.  
  440.  
  441.  
  442. GLboolean gl_AreTexturesResident( GLcontext *ctx, GLsizei n,
  443.                                   const GLuint *textures,
  444.                                   GLboolean *residences )
  445. {
  446.    GLboolean resident = GL_TRUE;
  447.    GLuint i;
  448.  
  449.    if (INSIDE_BEGIN_END(ctx)) {
  450.       gl_error( ctx, GL_INVALID_OPERATION, "glAreTexturesResident" );
  451.       return GL_FALSE;
  452.    }
  453.    if (n<0) {
  454.       gl_error( ctx, GL_INVALID_VALUE, "glAreTexturesResident(n)" );
  455.       return GL_FALSE;
  456.    }
  457.  
  458.    for (i=0;i<n;i++) {
  459.       struct gl_texture_object *t;
  460.       if (textures[i]==0) {
  461.          gl_error( ctx, GL_INVALID_VALUE, "glAreTexturesResident(textures)" );
  462.          return GL_FALSE;
  463.       }
  464.       t = find_texture_object( ctx, textures[i] );
  465.       if (t) {
  466.          /* we consider all valid texture objects to be resident */
  467.          residences[i] = GL_TRUE;
  468.       }
  469.       else {
  470.          gl_error( ctx, GL_INVALID_VALUE, "glAreTexturesResident(textures)" );
  471.          return GL_FALSE;
  472.       }
  473.    }
  474.    return resident;
  475. }
  476.  
  477.  
  478.  
  479. GLboolean gl_IsTexture( GLcontext *ctx, GLuint texture )
  480. {
  481.    if (INSIDE_BEGIN_END(ctx)) {
  482.       gl_error( ctx, GL_INVALID_OPERATION, "glIsTextures" );
  483.       return GL_FALSE;
  484.    }
  485.    if (texture>0 && find_texture_object(ctx,texture)) {
  486.       return GL_TRUE;
  487.    }
  488.    else {
  489.       return GL_FALSE;
  490.    }
  491. }
  492.  
  493.